package com.thank.concurrency.samples.sync;

import com.thank.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@ThreadSafe
@Slf4j
public class SynchronizedExample1 {

    // 修饰一个代码块
    public void test1(String obj) {
        synchronized (this) {
            for (int i = 0; i < 10; i++) {
                log.info("test1 - {} - {}",obj, i);
            }
        }
    }

    // 修饰一个方法
    // 注意: 这里与上面的方式有一个区别: 如果该类作为一个父类, 子类的该方法是带不上synchronized的,
    // 原因是synchronized不属于方法声明中的一部分, 如果子类也想要, 需要自己在子类方法上显示声明synchronized
    public synchronized void test2(String obj) {
        for (int i = 0; i < 10; i++) {
            log.info("test2 - {} -{}", obj, i);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample1 example1 = new SynchronizedExample1();
        SynchronizedExample1 example2 = new SynchronizedExample1();
        ExecutorService executorService = Executors.newCachedThreadPool();

        /*
         * 修饰一个代码块测试
         * 测试结果: 两个example的线程交替执行
         */
        executorService.execute(() -> example1.test1("exp1"));
        // 分别启动两个线程去执行, 下面这个不会等上面呢个
        executorService.execute(() -> example2.test1("exp2"));


       /*
        * 修饰一个方法测试
        * 与上面结果类似
        */
//        executorService.execute(() -> example1.test2("exp1"));
//        executorService.execute(() -> example2.test2("exp2"));

    }
}
